package com.jsu.hotelmanagement.service.serviceImpl;

import com.jsu.hotelmanagement.dao.RoomDao;
import com.jsu.hotelmanagement.observerModel.observer.RoomObserver;
import com.jsu.hotelmanagement.observerModel.thread.CheckOut;
import com.jsu.hotelmanagement.pojo.dto.*;
import com.jsu.hotelmanagement.pojo.po.OrdersInfoVO;
import com.jsu.hotelmanagement.pojo.vo.*;
import com.jsu.hotelmanagement.service.RoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Mo
 * @createTime 2022/12/7 11:44
 * @descripiton
 */
@Service
public class RoomServiceImpl implements RoomService {
    @Autowired
    RoomDao roomDao;

    @Autowired
    CheckOut checkOut;
    /**
     * 房间状态:
     * 0空闲,1已用,2已预定,3清理中, 4暂用
     */
    public static final int ROOM_VACANCY = 0;
    public static final int ROOM_USED = 1;
    public static final int ROOM_ORDERED = 2;
    public static final int ROOM_CLEANING = 3;
    public static final int ROOM_BANNED = 4;

    @Override
    public CommonResult getRoomStatistics() {
        List<RoomStatisticsStatusDTO> roomStatisticsStatusDTOList = roomDao.queryRoomStatistics();
        RoomStatisticsVO roomStatisticsVO = new RoomStatisticsVO();
        AtomicInteger totalNumber = new AtomicInteger();
        roomStatisticsStatusDTOList.forEach(e -> {
            switch (e.getStatusId()) {
                case 0:
                    roomStatisticsVO.setRoomVacancyNumber(e.getNumber());
                    totalNumber.addAndGet(e.getNumber());
                    break;
                case 1:
                    roomStatisticsVO.setRoomUsedNumber(e.getNumber());
                    totalNumber.addAndGet(e.getNumber());
                    break;
                case 2:
                    roomStatisticsVO.setRoomOrderedNumber(e.getNumber());
                    totalNumber.addAndGet(e.getNumber());
                    break;
                case 3:
                    roomStatisticsVO.setRoomRepairedNumber(e.getNumber());
                    totalNumber.addAndGet(e.getNumber());
                    break;
                case 4:
                    roomStatisticsVO.setRoomBannedNumber(e.getNumber());
                    totalNumber.addAndGet(e.getNumber());
                default:
                    break;
            }
        });
        roomStatisticsVO.setRoomNumber(totalNumber.get());
        return new CommonResult<>(200, "查询成功", roomStatisticsVO);
    }

    @Override
    public CommonResult queryRoomDetailInfoList() {
        List<RoomDetailInfoDTO> roomDetailInfoDTOList = roomDao.queryRoomDetailInfoList();
        List<RoomDetailInfoVO> roomDetailInfoVOList = new ArrayList<>();
        roomDetailInfoDTOList.forEach(roomDetailInfoDTO -> {
            RoomDetailInfoVO roomDetailInfoVO = new RoomDetailInfoVO();
            List<String> tagList = new ArrayList<>();
            tagList.add(roomDetailInfoDTO.getBedNumberTag());
            tagList.add(roomDetailInfoDTO.getRoomSizeTag());
            tagList.add(roomDetailInfoDTO.getMaxLoadTag());
            tagList.add(roomDetailInfoDTO.getNetworkTag());
            tagList.add(roomDetailInfoDTO.getBreakfastTag());
            tagList.add(roomDetailInfoDTO.getWindowTag());
            tagList.add(roomDetailInfoDTO.getTvTag());
            roomDetailInfoVO.setTagList(tagList);
            roomDetailInfoVO.setAttributes(roomDetailInfoDTO);
            roomDetailInfoVOList.add(roomDetailInfoVO);
        });
        return new CommonResult<>(200, "查询成功", roomDetailInfoVOList);
    }

    @Override
    @Transactional
    public CommonResult guestCheckOut(Integer roomId) {
        RoomUserRelationDTO roomUserRelationDTO = roomDao.queryRoomUserRelation(roomId);
        //  更改订单信息改为订单已完成，完成checkout记录
        int i = roomDao.updateUserRoomStatusCheckout(roomUserRelationDTO);
        //  将旅客对应的房间信息置为失效, 清除该用户房间正在使用的状态
        i += roomDao.updateRoomGuestHistories(roomUserRelationDTO);
        //  将房间状态置为空（应该置为清理中
        i += roomDao.updateRoomStatus(roomId, ROOM_VACANCY);
        if (i >= 3) {
            //  三条语句修改数据行数都大于1则说明都修改成功了
            return new CommonResult<>(200, "修改成功");
        } else {
            return new CommonResult<>(444, "错误");
        }
    }

    @Override
    public CommonResult updateRoomStatus(RoomStatusVO roomStatusVO) {
        int i =roomDao.updateRoomStatus(roomStatusVO.getRoomId(), roomStatusVO.getRoomStatus());
        if (i > 0) {
            return new CommonResult<>(200, "修改成功");
        } else {
            return new CommonResult<>(444, "修改失败");
        }
    }

    @Override
    public CommonResult finishedCleanStatus(Integer roomId) {
        Integer orderStatus = roomDao.queryOrderStatus(roomId);
        System.out.println(orderStatus);
        if (orderStatus == null){
            //  返回空闲状态
            roomDao.updateRoomStatus(roomId, ROOM_VACANCY);
            return new CommonResult<>(200, "清理完成");
        } else if (orderStatus == 1) {
            roomDao.updateRoomStatus(roomId, ROOM_ORDERED);
            return new CommonResult<>(200, "清理完成");
        } else if (orderStatus == 2) {
            //  返回使用状态
            roomDao.updateRoomStatus(roomId, ROOM_USED);
            return new CommonResult<>(200, "清理完成");
        }
        return new CommonResult<>(444, "处理异常");
    }

    @Override
    public CommonResult cancelOrder(Integer roomId) {
        int i = roomDao.cancelOrder(roomId);
        if (i > 0) {
            return new CommonResult(200, "取消成功");
        } else {
            return new CommonResult(444, "异常");
        }
    }

    @Override
    public CommonResult queryOrderUserInfo(Integer roomId) {
        List<OrderUserInfoVO> orderUserInfoVOList = roomDao.queryOrderUserInfo(roomId);
        System.out.println(orderUserInfoVOList);
        return new CommonResult(200, "查询成功", orderUserInfoVOList);
    }

    @Override
    public CommonResult queryRoomGuestInfo(Integer roomId) {
        List<RoomGuestInfoVO> roomGuestInfoVOList = roomDao.queryRoomGuestInfo(roomId);
        if (roomGuestInfoVOList != null) {
            CheckInOutTimeDTO checkInOutTimeDTO = roomDao.queryCheckInOutTime(roomId);
            for (RoomGuestInfoVO roomGuestInfoVO : roomGuestInfoVOList) {
                roomGuestInfoVO.setCheckInTime(checkInOutTimeDTO.getCheckInTime());
                roomGuestInfoVO.setCheckOutTime(checkInOutTimeDTO.getCheckOutTime());
            }
            return new CommonResult(200, "查询成功", roomGuestInfoVOList);
        } else {
            return new CommonResult(444, "该房间无入住旅客");
        }
    }

    @Override
    public CommonResult<Integer> insertOrdersInfo(OrdersInfoVO ordersInfoVO) {
        DelayQueue<RoomObserver> delayQueue = checkOut.getRoomObserverDelayQueue();
        RoomObserver roomObserver = new RoomObserver(ordersInfoVO.getRoomId(),ordersInfoVO.getEstimatedCheckOut());
        delayQueue.put(roomObserver);
        roomDao.insertOrdersInfo(ordersInfoVO);
        System.out.println("插入成功当前队列的长度为: " + delayQueue.size());
        return new CommonResult<>(200,"插入成功");
    }

    @Override
    public Integer modifyEndtime(Integer roomId) {
        RoomObserver[] queue = checkOut.getRoomObserverDelayQueue().toArray(new RoomObserver[0]);
        for(int i=0;i<queue.length;i++){
            if(queue[i].getRoomId().equals(roomId)){
                RoomObserver roomObserver = queue[i];
                checkOut.getRoomObserverDelayQueue().remove(roomObserver);
                roomObserver.setEndTime(roomDao.queryEndTime(roomId));
                checkOut.getRoomObserverDelayQueue().offer(roomObserver);
            }
        }
        return 1;
    }

    @Override
    @Transactional
    public CommonResult checkInUser(CheckInUserDTO checkInUserDTO) {
        System.out.println(checkInUserDTO);
        roomDao.addUser(checkInUserDTO.getUserInfoList());
        roomDao.updateRoomStatus(checkInUserDTO.getRoomId(), ROOM_USED);
        insertOrdersInfo(
                new OrdersInfoVO(checkInUserDTO.getUserInfoList().get(0).getUserId(),
                        checkInUserDTO.getRoomId(),
                        checkInUserDTO.getEstimatedCheckInTime(),
                        checkInUserDTO.getEstimatedCheckInTime(),
                        checkInUserDTO.getEstimatedCheckOutTime(),
                        2
                        )
        );
        roomDao.insertRoomGuestInfo(checkInUserDTO.getUserInfoList(), checkInUserDTO.getRoomId());
        return new CommonResult(200, "添加成功");
    }
}
